TimeMgr = {};

local delayFunDic = {};
local loopFunDic = {};

UpdateMgr:add(function()
    for i, v in pairs(delayFunDic) do
        if v ~= nil and Time.time >= v[3] and Time.frameCount > v[4] then
            v[1](table.unpack(v[2]));
            delayFunDic[i] = nil;
        end
    end
    for i, v in pairs(loopFunDic) do
        if v ~= nil and Time.time >= v[3] and Time.frameCount > v[4] then
            v[1](table.unpack(v[2]));
            if v[3] < 0 then
                v[4] = Time.frameCount + v[5] - 1;
            else
                v[3] = Time.time + v[5];
                v[4] = Time.frameCount;
            end
        end
    end
end)

function TimeMgr:delayFun(delay, handler, ...)
    local time = Time.time + delay;
    delayFunDic[handler] = { handler, { ... }, time, Time.frameCount };
    return handler;
end

function TimeMgr:delayFrame(frame, handler, ...)
    delayFunDic[handler] = { handler, { ... }, 0, Time.frameCount + frame - 1 };
    return handler;
end

function TimeMgr:removeDelayFun(handler)
    if handler then
        delayFunDic[handler] = nil;
    end
end

function TimeMgr:loopFun(interval, isCall, handler, ...)
    if isCall then
        handler(...);
    end
    local time = Time.time + interval;
    loopFunDic[handler] = { handler, { ... }, time, Time.frameCount, interval };
    return handler;
end

function TimeMgr:loopFrame(interval, isCall, handler, ...)
    if isCall then
        handler(...);
    end
    loopFunDic[handler] = { handler, { ... }, -1, Time.frameCount + interval - 1, interval };
    return handler;
end

function TimeMgr:removeLoopFun(handler)
    if handler then
        loopFunDic[handler] = nil;
    end

end